<script setup lang="tsx">
import { reactive, ref } from 'vue';
import { Button, Popconfirm, Tag } from 'ant-design-vue';
import { useTable, useTableOperate } from '@/hooks/common/table';
import {
  fetchGetRoleList,
  fetchDeleteRole,
  fetchDeleteRoles,
  fetchChangeRoleStatus
} from '@/service/api';
import { $t } from '@/locales';
import { enableStatusRecord } from '@/constants/business';
import RoleOperateDrawer, { type OperateType } from './modules/role-operate-drawer.vue';
import MenuAuthModal from './modules/menu-auth-modal.vue';
import ButtonAuthModal from './modules/button-auth-modal.vue';
import RoleSearch from './modules/role-search.vue';

const wrapperEl = ref<HTMLElement>();

const { columns, columnChecks, data, getData, getDataByPage, loading, mobilePagination, searchParams } =
  useTable({
    apiFn: fetchGetRoleList,
    apiParams: {
      current: 1,
      size: 10,
      status: null,
      roleName: null,
      roleCode: null
    },
    columns: () => [
      {
        key: 'index',
        title: $t('common.index'),
        width: 64,
        align: 'center',
        customRender: ({ index }) => index + 1
      },
      {
        key: 'roleName',
        title: $t('page.manage.role.roleName'),
        align: 'center',
        minWidth: 120,
        dataIndex: 'roleName'
      },
      {
        key: 'roleCode',
        title: $t('page.manage.role.roleCode'),
        align: 'center',
        minWidth: 120,
        dataIndex: 'roleCode'
      },
      {
        key: 'description',
        title: $t('page.manage.role.roleDesc'),
        align: 'center',
        minWidth: 120,
        dataIndex: 'description'
      },
      {
        key: 'roleSort',
        title: '显示顺序',
        align: 'center',
        width: 100,
        dataIndex: 'roleSort'
      },
      {
        key: 'status',
        title: $t('page.manage.role.roleStatus'),
        align: 'center',
        width: 100,
        dataIndex: 'status',
        customRender: ({ record }) => {
          if (record.status === null) {
            return null;
          }

          const label = $t(enableStatusRecord[record.status]);

          return <Tag color={record.status === '0' ? 'success' : 'error'}>{label}</Tag>;
        }
      },
      {
        key: 'createTime',
        title: '创建时间',
        align: 'center',
        width: 160,
        dataIndex: 'createTime'
      },
      {
        key: 'operate',
        title: $t('common.operate'),
        align: 'center',
        width: 280,
        customRender: ({ record }) => (
          <div class="flex-center gap-8px">
            <Button type="primary" ghost size="small" onClick={() => edit(record.id)}>
              {$t('common.edit')}
            </Button>
            <Button size="small" onClick={() => handleMenuAuth(record)}>
              菜单权限
            </Button>
            <Button size="small" onClick={() => handleButtonAuth(record)}>
              按钮权限
            </Button>
            <Button
              type={record.status === '0' ? 'default' : 'primary'}
              size="small"
              onClick={() => toggleStatus(record.id, record.status)}
            >
              {record.status === '0' ? '禁用' : '启用'}
            </Button>
            <Popconfirm title={$t('common.confirmDelete')} onConfirm={() => handleDelete(record.id)}>
              <Button danger size="small">
                {$t('common.delete')}
              </Button>
            </Popconfirm>
          </div>
        )
      }
    ]
  });

const {
  drawerVisible,
  operateType,
  editingData,
  handleAdd,
  handleEdit,
  checkedRowKeys,
  onBatchDeleted,
  onDeleted
} = useTableOperate(data, getData);

// 菜单权限弹窗
const menuAuthVisible = ref(false);
const menuAuthRoleData = ref<Api.SystemManage.Role | null>(null);

// 按钮权限弹窗
const buttonAuthVisible = ref(false);
const buttonAuthRoleData = ref<Api.SystemManage.Role | null>(null);

async function handleBatchDelete() {
  const { error } = await fetchDeleteRoles(checkedRowKeys.value);
  if (!error) {
    onBatchDeleted();
  }
}

async function handleDelete(id: number) {
  const { error } = await fetchDeleteRole(id);
  if (!error) {
    onDeleted();
  }
}

async function toggleStatus(id: number, status: string) {
  const newStatus = status === '0' ? '1' : '0';
  const { error } = await fetchChangeRoleStatus(id, newStatus);
  if (!error) {
    window.$message?.success('状态修改成功');
    getData();
  }
}

function handleMenuAuth(record: Api.SystemManage.Role) {
  menuAuthRoleData.value = record;
  menuAuthVisible.value = true;
}

function handleButtonAuth(record: Api.SystemManage.Role) {
  buttonAuthRoleData.value = record;
  buttonAuthVisible.value = true;
}

function edit(id: number) {
  handleEdit(id);
}


</script>

<template>
  <div ref="wrapperEl" class="flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
    <RoleSearch v-model:model="searchParams" @reset="getData" @search="getData" />

    <!-- 表格区域 -->
    <ACard
      title="角色列表"
      :bordered="false"
      :body-style="{ paddingTop: '0px' }"
      class="card-wrapper sm:flex-1-hidden"
    >
      <template #extra>
        <TableHeaderOperation
          v-model:columns="columnChecks"
          :disabled-delete="checkedRowKeys.length === 0"
          :loading="loading"
          @add="handleAdd"
          @delete="handleBatchDelete"
          @refresh="getData"
        />
      </template>
      <ATable
        :columns="columns"
        :data-source="data"
        size="small"
        :scroll="{ x: 'max-content' }"
        :loading="loading"
        row-key="id"
        :pagination="mobilePagination"
        class="h-full"
      />
    </ACard>

    <!-- 角色操作抽屉 -->
    <RoleOperateDrawer
      v-model:visible="drawerVisible"
      :operate-type="operateType"
      :row-data="editingData"
      @submitted="getData"
    />

    <!-- 菜单权限弹窗 -->
    <MenuAuthModal
      v-model:visible="menuAuthVisible"
      :role-data="menuAuthRoleData"
    />

    <!-- 按钮权限弹窗 -->
    <ButtonAuthModal
      v-model:visible="buttonAuthVisible"
      :role-data="buttonAuthRoleData"
    />
  </div>
</template>

<style scoped></style>
